package utils;

import com.google.gson.JsonObject;
import constants.Configurations;
import constants.Default;
import constants.api.ApiContext;
import play.Logger;
import play.Play;
import play.cache.Cache;
import play.libs.Codec;
import play.mvc.Scope;
import org.apache.commons.lang.StringUtils;

import java.awt.*;
import java.io.*;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 常用方法工具类
 * 
 * @author yangzhi@djcars.cn
 * @createDate 2012-9-2
 * 
 */
public class Utils {

    public static Boolean isLetterOrNumber(String text){
        if(isNullOrEmpty(text)) {
            return false;
        }
        return text.matches("^[a-zA-Z0-9]+$");
    }


    //图片后缀数组
    public static final String imgExtArray []  = {"bmp","dib","gif","jfif","jpe","jpeg","jpg","png","tif","tiff","ico"};

    public static String getExtName(String url) {
        String extName=url.substring(url.lastIndexOf(".") + 1).toString();
        //循环判断是否存在此后缀
        for (String ext: imgExtArray){
            if(ext.toLowerCase().equals(extName.toLowerCase())){
                return extName;
            }
        }
        return extName;
    }

    /**
     * 转换float 后面小数点的0
     * @param s
     * @return
     */
    public static String subZeroAndDot(String s){
        if(s.indexOf(".") > 0){
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }

    /**
     * 将按,分隔的字符串转换为长整数数组
     * 
     * @param str
     * @return
     */
    public static Long[] toLongArray(String str) {
        if (StringUtils.isEmpty(str))
            return new Long[0];

        String[] segs = str.split(",");
        Long[] results = new Long[segs.length];
        for (int i = 0; i < segs.length; i++) {
            results[i] = asLong(segs[i]);
            if (results[i] == null) {
                return new Long[0];
            }
        }
        return results;
    }
    
    
    /**
     * 将按,分隔的字符串转换为整数数组
     * @param str
     * @return
     */
    public static Integer[] toIntegerArray(String str) {
        if (StringUtils.isEmpty(str))
            return null;

        String[] segs = str.split(",");
        Integer[] results = new Integer[segs.length];
        for (int i = 0; i < segs.length; i++) {
            results[i] = asInteger(segs[i]);
            if (results[i] == null) {
                return null;
            }
        }
        return results;
    }
    
    /**
     * 将按,分隔的字符串转换为整数数组
     * @param str
     * @return
     */
    public static List<Integer> toIntegerList(String str) {
        if (StringUtils.isEmpty(str)) {
            return null;
        }

        String[] segs = str.split(",");
        List<Integer> results = new ArrayList<Integer>();
        for (int i = 0; i < segs.length; i++) {
            Integer tmpI = asInteger(segs[i]);
            if (tmpI != null){
                results.add(tmpI);
            }
        }
        return results;
    }

    public static List<Long> toLongList(String str) {
        if (StringUtils.isEmpty(str)) {
            return null;
        }

        String[] segs = str.split(",");
        List<Long> results = new ArrayList<Long>();
        for (int i = 0; i < segs.length; i++) {
            Long tmpI = asLong(segs[i]);
            if (tmpI != null){
                results.add(tmpI);
            }
        }
        return results;
    }

    /**
     * 转换为长整数
     * 
     * @param value
     * @return
     */
    public static Long asLong(String value) {
        if (value == null) {
            return null;
        }
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException e) {
            return null;
        }
    }
    
    /**
     * 转换为整数
     * @param value
     * @return
     */
    public static Integer asInteger(String value) {
        if (value == null) {
            return null;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return null;
        }
    }
    
    /**
     * 判断字符串是否是null或者空字符串
     * 
     * @param text
     */
    public static boolean isNullOrEmpty(String text) {
        return text == null || text.length() == 0;
    }


    /**
     * 检查页面
     * @param strings
     * @param page
     * @param type 1  equals 2 contains
     */
    public static boolean  checkPage(String[] strings,String page,Integer type){
        for (String str:strings){
            if(type == 1) {
                if (page.toLowerCase().equals(str.toLowerCase())) {
                    return true;
                }
            }else if(type ==2){
                if (page.toLowerCase().contains(str.toLowerCase())) {
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 检查页面
     * @param strings
     * @param page
     */
//    public static boolean  checkPage(String[] strings,String page){
//        for (String str:strings){
//            if(page.toLowerCase().equals(str.toLowerCase())){
//                return true;
//            }
//        }
//        return false;
//    }

    /**
     * 检查字符串长度是否超过限制，若超过则切断
     * @param text
     * @param max
     * @return
     */
    public static String cutText(String text, Integer max){
        if(StringUtils.isEmpty(text) || max == null){
            return text;
        }
        if(text.length() > max){
            return text.substring(0, max);
        }
        return text;
    }




    /**
     * 改进的32位FNV算法，用于使用动态参数的方法生成缓存key
     *
     * @param data 字符串
     *
     * @return int值
     */
    public static int FNVHash(String data) {
        final int p = 16777619;
        int hash = (int) 2166136261L;
        for (int i = 0; i < data.length(); i++) {
            hash = (hash ^ data.charAt(i)) * p;
        }
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;
        return hash;
    }


    /**
     * 根据url 和参数 获取值
     * @param url
     * @param parameter
     * @return
     */
    public static String getParValue(String url,String parameter){
        String result="";
        if(isNullOrEmpty(url)){
            return  result;
        }
        //判断是否存在?
        Integer start=url.indexOf("?");

        if(start>0){
           String content=url.substring(start+1,url.length());
           if(content.indexOf("&")>0){
               String[] strContent=content.split("&");
               if(strContent.length>0){
                   for (int j=0;j<strContent.length;j++) {
                       String[] strs = strContent[j].split("=");
                       if (strs.length > 0) {
                           for (int k = 0; k < strs.length; k++) {
                               if (strs[k].equals(parameter)) {
                                   result =String.valueOf(strs[k+1]).trim();
                               }
                           }
                       }
                   }
               }
           }else{
              String[] str=content.split("=");
              if(str.length>0) {
                  for (int i=0;i<str.length;i++){
                      if(str[i].equals(parameter)){
                          result=String.valueOf(str[i+1]).trim();
                      }
                  }
              }
           }
        }
        return result;
    }


    private static final String[] htmlCharacters = new String[] { "\"", "'","\n" };
    private static final String[] htmlCharacterReplacements = new String[] { "\\&#34;", "\\&#39;","\\n"};

    /**
     * 对 " '  进行转义 用于HospApp方法中字符串中特殊字符替换
     * @param content
     * @return
     */
    public  static String quoteHostValue(String content){
        if (StringUtils.isEmpty(content)) {
            return "";
        }
        return StringUtils.replaceEach(content, htmlCharacters, htmlCharacterReplacements);
    }


    private static final String[] commentCharacters = new String[] { "\n" };
    private static final String[] commentCharacterReplacements = new String[] { "<br/>"};



    /**
     * 替换评论内容特殊字符
     * @param content
     * @return
     */
    public static String quoteCommentContent(String content){
        if(StringUtils.isEmpty(content)){
            return  "";
        }
        return  StringUtils.replaceEach(content,commentCharacters,commentCharacterReplacements);
    }


    private static Properties positionIds;
    private static long lastPositionIdsModifyTime = 0L;

    private static Properties vcIds;
    private static long lastVcIdsModifyTime = 0L;

    private static Properties faceIds;
    private static long lastFaceIdsModifyTime = 0L;


    /**
     * 获取对应页面广告位编号
     * @param page 页面 如 index
     * @param key 页面广告位序号 indexOne
     * @return
     */
    public static Integer  getPositionId(String page,String key){
        Properties properties=getFileIds("conf/position.conf",positionIds,lastPositionIdsModifyTime);
        Integer positionId=0;
        String positionIds=String.valueOf(properties.get(page));
        for (String str:positionIds.split(",")){
            if(str.startsWith(key)){
                positionId=Integer.parseInt(str.split("_")[1]);
            }
        }
        return  positionId;
    }


    public static String getVcIds(String key){
        Properties properties=getFileIds("conf/versioncode.conf",vcIds,lastVcIdsModifyTime);
        if(properties.size()>0) {
            String id = String.valueOf(properties.get(key));
            if (id.equals("null")) {
                return null;
            } else {
                return id;
            }
        }
        return  null;
    }

    public static List getFace () {
        Properties properties = getFileIds("conf/face.conf", faceIds, lastFaceIdsModifyTime);
        if (properties.size() > 0) {
            List list = new ArrayList(properties.entrySet());
            return list;
        }
        return  null;
    }

    /**
     * 获取配置
     * @return
     */
    private static Properties getFileIds(String path,Properties ids,Long time){

        Date now = new Date();
        //2分钟后检查一次
        if(ids == null || (now.getTime() - time) > 120000){
            File file = Play.getFile(path);
            if(file.exists()){
                if(file.lastModified() > time){
                    //文件有更新则重新刷新
                    try {
                        ids = new Properties();
                        FileInputStream stream = new FileInputStream(file);
                        InputStreamReader reader = new InputStreamReader(stream, "utf-8");
                        ids.load(reader);
                        reader.close();
                        stream.close();
                        time = file.lastModified();
                    } catch (Exception ex) {
                        Logger.error(ex, "读取\""+path+"\"配置文件出错");
                    }
                }
            }else{
                ids = null;
            }
        }
        return ids;
    }

    /**
     * 判断文件是否存在
     * @param path
     * @return
     */
    public static boolean exitFile(String path){
        if(StringUtils.isEmpty(path)){
            return false;
        }
        path="app/views"+path;
        //linux环境
        File file = new File(Play.applicationPath+"/precompiled/templates/"+path);
        //window环境
        if(!file.exists()){
            file=Play.getFile(path);
        }
        return  file.exists();
    }

    public static boolean exitImageFile(String path){
        if(StringUtils.isEmpty(path)){
            return false;
        }
        //linux环境
        File file = new File(path);
        //window环境
        if(!file.exists()){
            file=Play.getFile(path);
        }
        return  file.exists();
    }

    /**
     * 格式化文件的大小
     *
     * @param size 文件的大小，单位：字节
     * @return 文件的大小表示形式，如 :102KB, 23MB
     */
    public static String formatFileSize(Integer size) {
        DecimalFormat df = new DecimalFormat("0.00");
        if (null == size) {
            return null;
        }
        if (size < 1024) {
            return size + "bytes";
        } else if (size < (1024 * 1024)) {
            return df.format(size / 1024.0) + "KB";
        } else {
            return df.format(size / (1024.0 * 1024.0)) + "MB";
        }
    }

    /**
     * 获取随机数
     * @param total
     * @return
     */
    public static Integer getRandom(Integer total){
        Random random=new Random();
        return  random.nextInt(total);
    }

    /**
     * 格式化浏览数
     * @param number
     * @return
     */
    public static String formatNumber(Integer number){
        if(number>0 && number>10000){
            return  String.valueOf(number/10000).concat("万+");
        }else{
            return  number.toString();
        }
    }


    public static String createTimeRndSequnceCode() {
        Date time = new Date();
        StringBuffer buffer = new StringBuffer();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        buffer.append(dateFormat.format(time));

        // 增加随机值
        String uuid = Codec.UUID().substring(0, 6);
        buffer.append(uuid);
        return buffer.toString();
    }

    /**
     *   检查图片域名
     * @param url
     */
    public static Boolean checkImageUrl(String url){
       if(isNullOrEmpty(url)){
           return  false;
       }
       return  url.trim().toLowerCase().indexOf("djcars.cn")>-1?true:false;
    }

    /**
     * 将127.0.0.1形式的IP地址转换成十进制整数，这里没有进行任何错误处理
     *
     * @param strIp
     * @return
     */
    public static long ipToLong(String strIp) {
        if (StringUtils.isEmpty(strIp)) {
            return 0;
        }

        long[] ip = new long[4];

        // 先找到IP地址字符串中.的位置
        int position1 = strIp.indexOf(".");
        int position2 = strIp.indexOf(".", position1 + 1);
        int position3 = strIp.indexOf(".", position2 + 1);

        // 将每个.之间的字符串转换成整型
        ip[0] = Long.parseLong(strIp.substring(0, position1));
        ip[1] = Long.parseLong(strIp.substring(position1 + 1, position2));
        ip[2] = Long.parseLong(strIp.substring(position2 + 1, position3));
        ip[3] = Long.parseLong(strIp.substring(position3 + 1));

        return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
    }

    /**
     * 将十进制整数形式转换成127.0.0.1形式的ip地址
     *
     * @param longIp
     * @return
     */
    public static String longToIP(long longIp) {
        StringBuffer sb = new StringBuffer("");
        // 直接右移24位
        sb.append(String.valueOf((longIp >>> 24)));
        sb.append(".");
        // 将高8位置0，然后右移16位
        sb.append(String.valueOf((longIp & 0x00FFFFFF) >>> 16));
        sb.append(".");
        // 将高16位置0，然后右移8位
        sb.append(String.valueOf((longIp & 0x0000FFFF) >>> 8));
        sb.append(".");
        // 将高24位置0
        sb.append(String.valueOf((longIp & 0x000000FF)));
        return sb.toString();
    }

    /**
     * wx.djcars.cn 替换 circleh5.djcars.cn
     * @param url
     * @return
     */
    public  static  String getReplaceUrl(String url){
        url = url.replaceAll("wx.djcars.cn","circleh5.djcars.cn");
        url = url.replaceAll("wx.test.djcars.cn","circleh5.test.djcars.cn");
        return url;
    }

    public static final String REGEX_IS_MOBILE= "(?is)(^1[3|4|5|8][0-9]\\d{4,8}$)";
    public static final String REGEX_IS_DOUBLE= "(?is)(^1[3|4|5|8][0-9]\\d{4,8}$)";
    /**
     * 检测手机号
     * @param text
     * @return
     */
    public static Boolean isMobilephone(String text){
        if(isNullOrEmpty(text)) {
            return false;
        }

        Pattern p=Pattern.compile(REGEX_IS_MOBILE);
        Matcher m=p.matcher(text);

        return m.matches();
    }

    /**
     * 检测浮点型
     * @param str
     * @return
     */
    public static Boolean isDouble(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile(REGEX_IS_DOUBLE);
        return pattern.matcher(str).matches();
    }

    public static String getUUID() {
        try {
            if (Scope.Session.current().contains("uuid")) {
                String uuid = String.valueOf(Scope.Session.current().get("uuid"));
                return uuid;
            } else if (ApiContext.apiContext.get() != null){
                ApiContext context = ApiContext.apiContext.get();
                return context.uuid;
            }else{//TODO 从header取
                String uuid = UUID.randomUUID().toString();
                Scope.Session.current().put("uuid", String.valueOf(uuid));
                return uuid;
            }
        }catch (Exception e){
            Logger.error("error when getUUID, e:"+e.getMessage());
            return "";
        }
    }


    private static Pattern HTML_PATTERN = Pattern.compile("<[^>]*>|&nbsp;");
    /**
     * 去除HTML标记
     * @param str
     * @return
     */
    public static String removeHtml(String str) {
        Matcher matcher = HTML_PATTERN.matcher(str.toLowerCase());
        str = matcher.replaceAll("");
        return str;
    }



    /**
     * 判断一个字符是否是中文
     * @param c
     * @return
     */
    public static boolean isChinese(char c) {
        return c >= 0x4E00 &&  c <= 0x9FA5;// 根据字节码判断
    }

    /**
     * 判断一个字符串是否含有中文
     * @param str
     * @return
     */
    public static boolean isChinese(String str) {
        if (str == null) {
            return false;
        }
        for (char c : str.toCharArray()) {
            // 有一个中文字符就返回
            if (isChinese(c)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取随机字母数字组合
     *
     * @param length 字符串长度
     * @return
     */
    public static String getRandomCharAndNumr(Integer length) {
        String str = "";
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            boolean b = random.nextBoolean();
            if (b) { // 字符串
                // int choice = random.nextBoolean() ? 65 : 97; 取得65大写字母还是97小写字母
                str += (char) (97 + random.nextInt(26));// 取得大写字母
            } else { // 数字
                str += String.valueOf(random.nextInt(10));
            }
        }
        return str;
    }

    //dupp省市区
    public static String[] duppOne ={"mng.notice.sms.create","mng.province.getList","city.getListByProvinceId","area.getList","mng.zone.getList"};

    /**
     * 访问dupp
     * @param path
     * @return
     */
    public static Integer getDuppNumber(String path){
        Integer result = 2;
        if (Arrays.asList(duppOne).contains(path)){
            result =1;
        }
        return  result;
    }

    /**
     * 匹配编辑器内容图片地址的name
     * eg :https://imagegoods-beta.djcars.cn/1/156257229003207000.png
     * eg :https://videogoods-beta.djcars.cn/1/156258156407626000.mp4
     * @param intro
     * @return
     */
   private static final  String patternString = "(https?|http)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]";

    public static List<Long> getUrlNameList(String intro,Integer type){
        List<Long> list = new ArrayList<>();

        Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);

        Matcher matcher = pattern.matcher(intro);
        List<String> imageUrls = new ArrayList<>();
        List<String> videoUrls = new ArrayList<>();
        while (matcher.find()) {
            String link=matcher.group();

            Logger.info("link:"+link);
//            String imageDomain=Configurations.ossBucketImgUrl;
//            String videoDomain=Configurations.ossBucketVideoUrl;

            if (link.indexOf("imagegoods")>0){
                imageUrls.add(link);
            }else if(link.indexOf("videogoods")>0){
                videoUrls.add(link);
            }
        }
        if (type.equals(Default.typeId.image)){
            if(imageUrls.size()>0) {
                for (Integer i = 0;i<imageUrls.size();i++){
                    String imgUrl = imageUrls.get(i);
                    Long name =Long.parseLong(imgUrl.substring(imgUrl.lastIndexOf("/")+1,imgUrl.lastIndexOf(".")));
                    list.add(name);
                }
            }

        }else if(type.equals(Default.typeId.video)){
            if(videoUrls.size()>0) {
                for (Integer j = 0;j<videoUrls.size();j++){
                    String videoUrl = videoUrls.get(j);
                    Long name =Long.parseLong(videoUrl.substring(videoUrl.lastIndexOf("/")+1,videoUrl.lastIndexOf(".")));
                    list.add(name);
                }
            }
        }
        return  list;
    }


    /**
     * 返回价格*100的分
     * @param dPrice 元
     * @return
     */
    public static Integer getIntPrice(Double dPrice){
        Integer result=0;
        if (dPrice>0) {
            BigDecimal a1 = new BigDecimal(Double.toString((dPrice)));
            BigDecimal a2 = new BigDecimal(Double.toString((100)));
            result= a1.multiply(a2).intValue();
        }
        return  result;
    }


    /**
     * 返回价格/100的元
     * @param fPrice
     * @return
     */
    public static String getStringPrice(Integer fPrice){
        BigDecimal  result =new BigDecimal(fPrice);
        if (fPrice>0) {
            result=result.divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);
        }
        return String.valueOf(result);
    }

    /**
     * 自定义折扣比例
     * @param dPrice
     * @param number
     * @return
     */
    public static Integer getIntPrice(Double dPrice,Integer number){
        Integer result=0;
        if (dPrice>0) {
            BigDecimal a1 = new BigDecimal(Double.toString((dPrice)));
            BigDecimal a2 = new BigDecimal(Double.toString((number)));
            result= a1.multiply(a2).intValue();
        }
        return  result;
    }

    public static String getStringPrice(Integer fPrice,Integer number){
        BigDecimal  result =new BigDecimal(fPrice);
        if (fPrice>0) {
            result=result.divide(new BigDecimal(number),1,BigDecimal.ROUND_HALF_UP);
        }
        return String.valueOf(result);
    }
    /**
     * BASE64Encoder 加密
     * @param data
     *            要加密的数据
     * @return 加密后的字符串
     */
    public static String encryptBASE64(byte[] data) {
        // BASE64Encoder encoder = new BASE64Encoder();
        // String encode = encoder.encode(data);
        // 从JKD 9开始rt.jar包已废除，从JDK 1.8开始使用java.util.Base64.Encoder
        Base64.Encoder encoder = Base64.getEncoder();
        String encode = encoder.encodeToString(data);
        return encode;
    }
    /**
     * BASE64Decoder 解密
     * @param data
     *            要解密的字符串
     * @return 解密后的byte[]
     * @throws Exception
     */
    public static byte[] decryptBASE64(String data) throws Exception {
        // BASE64Decoder decoder = new BASE64Decoder();
        // byte[] buffer = decoder.decodeBuffer(data);
        // 从JKD 9开始rt.jar包已废除，从JDK 1.8开始使用java.util.Base64.Decoder
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] buffer = decoder.decode(data);
        return buffer;
    }

    /**
     * 文件流转文件
     * @param ins
     * @param file
     */
    public static void inputStreamToFile(InputStream ins, File file){
        OutputStream os= null;
        try {
             os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }finally {
            if (os!=null) {
                try {
                    os.close();
                    ins.close();
                }catch (IOException io){

                }
            }
        }
    }

    /**
     * 创建文件
     * @param filePath
     * @return
     */
    public static File getFile(String filePath){
        File file = new File(filePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try {
            //先判断是否存在删除
            if(file.exists()){
                file.delete();
            }
            //然后新增
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    public static List<String> compareString(String str1,String str2){
        List<String> result = new ArrayList<>();
        if (!Utils.isNullOrEmpty(str1) && !Utils.isNullOrEmpty(str2)){
             String[] userRoleIds=str1.split(",");
            String[] tagRoleIds=str1.split(",");
             if (userRoleIds.length>0 && tagRoleIds.length>0) {
                 for (Integer i = 0; i < userRoleIds.length; i++) {
                     String roleId = userRoleIds[i];
                     for (Integer j =0;j<tagRoleIds.length;j++){
                         String tagRoleId = tagRoleIds[j];
                         if (tagRoleId.equals(roleId)){
                             result.add(tagRoleId);
                         }
                     }
                 }
             }
        }
        return  result;
    }
}
